Added fallback non-SSE routine if the input buffer is not aligned to 16
authorJan Heller <jheller@svn.gnome.org>
Thu, 12 Jun 2008 17:10:55 +0000 (17:10 +0000)
committerJan Heller <jheller@src.gnome.org>
Thu, 12 Jun 2008 17:10:55 +0000 (17:10 +0000)
2008-06-12  Jan Heller  <jheller@svn.gnome.org>

        * extensions/sse-fixups.c (conv_rgbaF_linear_rgb8_linear),
        (conv_rgbaF_linear_rgba8_linear): Added fallback non-SSE routine
        if the input buffer is not aligned to 16 bytes.

svn path=/trunk/; revision=324

ChangeLog
extensions/sse-fixups.c

index 45c4f951167128629f0b1364d83ca4e19a36af5b..caf521e212c7b9c434c1d37470c2121730f01711 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-12  Jan Heller  <jheller@svn.gnome.org>
+
+       * extensions/sse-fixups.c (conv_rgbaF_linear_rgb8_linear),
+       (conv_rgbaF_linear_rgba8_linear): Added fallback non-SSE routine 
+       if the input buffer is not aligned to 16 bytes.
+
 2008-06-05  Jan Heller  <jheller@svn.gnome.org>
 
        * AUTHORS: Updated contact info.
index f893923b40ba31e3ad8471bd7f1cf04f46e0d0a3..1cf90abad39b453c22a913bcf47d67fd495e656e 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "babl.h"
 #include "babl-cpuaccel.h"
+#include "extensions/util.h"
 
 #define INLINE inline
 
@@ -49,28 +50,53 @@ conv_rgbaF_linear_rgb8_linear (unsigned char *src,
                                long           samples)
 {
   long n = samples;
-  g4float *g4src = (g4float *) src;
-  g4float v;
 
-  union {
-   g2int si; 
-   unsigned char c[8];
-  } u;
-
-  while (n--)
+  if ((int) src & 0xF)
     {
-       v = *g4src++ * g4float_ff;
-       v = g4float_min(v, g4float_ff);
-       v = g4float_max(v, g4float_zero);
-       u.si = g4float_cvt2pi (v);
-       *dst++  = u.c[0];
-       *dst++  = u.c[4];
-       v = g4float_movhl (v, v);
-       u.si = g4float_cvt2pi (v);  
-       *dst++  = u.c[0];
+      // nonaligned buffers, we have to use fallback x87 code
+      float *fsrc = (float *) src;
+      int v;
+
+      while (n--)
+        {
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+         
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+
+          fsrc++;
+        }
+    }
+  else   
+    {
+      // all is well, buffers are SSE compatible
+      g4float *g4src = (g4float *) src;
+      g4float v;
+
+      union {
+       g2int si; 
+       unsigned char c[8];
+      } u;
+
+      while (n--)
+        {
+           v = *g4src++ * g4float_ff;
+           v = g4float_min(v, g4float_ff);
+           v = g4float_max(v, g4float_zero);
+           u.si = g4float_cvt2pi (v);
+           *dst++  = u.c[0];
+           *dst++  = u.c[4];
+           v = g4float_movhl (v, v);
+           u.si = g4float_cvt2pi (v);  
+           *dst++  = u.c[0];
+        }
+
+      g4float_emms ();
     }
-
-  g4float_emms ();
 
   return samples;
 }
@@ -82,29 +108,54 @@ conv_rgbaF_linear_rgba8_linear (unsigned char *src,
                                 long           samples)
 {
   long n = samples;
-  g4float *g4src = (g4float *) src;
-  g4float v;
-
-  union {
-   g2int si; 
-   unsigned char c[8];
-  } u;
-
-  while (n--)
+  if ((int) src & 0xF)
     {
-       v = *g4src++ * g4float_ff;
-       v = g4float_min(v, g4float_ff);
-       v = g4float_max(v, g4float_zero);
-       u.si = g4float_cvt2pi (v);
-       *dst++  = u.c[0];
-       *dst++  = u.c[4];
-       v = g4float_movhl (v, v);
-       u.si = g4float_cvt2pi (v);  
-       *dst++  = u.c[0];
-       *dst++  = u.c[4];
+      // nonaligned buffers, we have to use fallback x87 code
+      float *fsrc = (float *) src;
+      int v;
+
+      while (n--)
+        {
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+         
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+
+          v = rint (*fsrc++ * 255.0);
+          *dst++ = (v < 0) ? 0 : ((v > 255) ? 255 : v);
+        }
+    }
+  else   
+    {
+      // all is well, buffers are SSE compatible
+      g4float *g4src = (g4float *) src;
+      g4float v;
+
+      union {
+       g2int si; 
+       unsigned char c[8];
+      } u;
+
+      while (n--)
+        {
+           v = *g4src++ * g4float_ff;
+           v = g4float_min(v, g4float_ff);
+           v = g4float_max(v, g4float_zero);
+           u.si = g4float_cvt2pi (v);
+           *dst++  = u.c[0];
+           *dst++  = u.c[4];
+           v = g4float_movhl (v, v);
+           u.si = g4float_cvt2pi (v);  
+           *dst++  = u.c[0];
+           *dst++  = u.c[4];
+        }
+
+      g4float_emms ();
     }
-
-  g4float_emms ();
 
   return samples;
 }